use std::io::{TcpListener, TcpStream};
use std::io::{Acceptor, Listener};
use std::thread::Thread;

use std::str;
use std::io;

fn main() {
    let listener = TcpListener::bind("127.0.0.1:9090").unwrap();
    let mut acceptor = listener.listen().unwrap();

    for stream in acceptor.incoming() {
        match stream {
            Ok(stream) => {
                Thread::spawn(move || {
                    handle_client(stream);
                });
            },
            Err(e) => {
                println!("Error: {:?}", e);
            },
        }
    }

    drop(acceptor);
}

const TCP_BUFSIZE: usize = 1us << 10;

fn handle_client(mut stream: TcpStream) {
    println!("client {} connected!", stream.peer_name().unwrap());

    // read data
    let mut buf = [0u8; TCP_BUFSIZE];

    loop {
        match stream.read(&mut buf) {
            Ok(data_len) => {
                print!("data: {}, length: {}", str::from_utf8(buf.slice(0, data_len)).unwrap(), data_len);
                stream.write(buf.slice(0, data_len)).unwrap();
            },
            Err(e) => {
                if e.kind == io::EndOfFile {
                    println!("client {} closed!", stream.peer_name().unwrap());
                } else {
                    println!("unknown error of client {}: {}!", stream.peer_name().unwrap(), e);
                }

                // an error arises, just exit the loop and the thread will teminate too.
                break;
            },
        }
    }
}
